package com.dp.server.backend.servicios;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import org.apache.tools.ant.taskdefs.Sleep;

import backend.entry.Mensaje;

import com.dp.client.dto.Fecha;
import com.dp.client.dto.ResultadosQuerySimulacionDTO;
import com.dp.server.backend.PaqueteBackend;
import com.dp.server.backend.RutaDeVueloBackend;
import com.google.gson.Gson;

public class ServiciosBackend {
	public static final String PAQUETES_PREFIJO = "paquetes";
	public static final String GENERA_RUTAS = "genera_rutas";
	public static final String SELECCIONA = "selecciona";
	public static final String SIMULACION_PREFIJO = "simulacion";
	public static final String SIMULA_SIMPLE = "simula_simple";
	public static final String CAPACIDAD_ALMACEN = "capacidad_almacen";
	public static final String ESPACIO_LLENO_ALMACEN = "espacio_lleno_almacen";
	public static final String CAPACIDAD_DISPONIBLE_ALMACEN = "capacidad_disponible_almacen";
	public static final String START = "start";
	public static final String RESTART = "restart";
	public static final String CREAR_SESION_SIMULACION = "crear_sesion";
	public static final String START_SIMULACION = "iniciar_simulacion";
	public static final String CAMBIO_CAPACIDAD_CONEXION = "cambiar_capacidad_conexion";
	public static final String CAMBIO_CAPACIDAD_ALMACEN = "cambiar_capacidad_almacen";
	public static final String GET_DATOS_WINDOW_SIMULACION = "get_datos_simulacion_para_intervalo_de_tiempo";
		
	public String SimulacionSimple() throws UnknownHostException, IOException{
		String result = "";
		Gson gson = new Gson();
	    Socket socket = new Socket("localhost", 51717);
    	PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	        
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(SIMULACION_PREFIJO);
	    mensaje.addLinea(SIMULA_SIMPLE);
	    printToBackend(pw, mensaje);
	    while(scan.hasNextLine())
	    	result += "\n" + scan.nextLine();
	        
	    response.close();
	    socket.close();
	    pw.close();
	    return result;
	}
	private void printToBackend(PrintWriter pw, Mensaje mensaje) {
	    pw.println(new Gson().toJson(mensaje, Mensaje.class));
	    pw.flush();
	}
	public boolean EjecutaRuta(RutaDeVueloBackend ruta, PaqueteBackend paquete) throws UnknownHostException, IOException{
		boolean result = false;
		Gson gson = new Gson();
	    Socket socket = new Socket("localhost", 51717);
    	PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	       
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(PAQUETES_PREFIJO);
	    mensaje.addLinea(SELECCIONA);
	    mensaje.addLinea(gson.toJson(paquete, PaqueteBackend.class));
	    mensaje.addLinea(gson.toJson(ruta, RutaDeVueloBackend.class));
	    printToBackend(pw, mensaje);
	    result = Boolean.parseBoolean(scan.nextLine());
	        
	    response.close();
	    socket.close();
	    pw.close();
	    return result;
	}
	
	public RutaDeVueloBackend[] generaRutasDevuelo(PaqueteBackend paquete) throws UnknownHostException, IOException{
		RutaDeVueloBackend[] result = null;
		Gson gson = new Gson();
	    Socket socket = new Socket("localhost", 51717);
	    OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(PAQUETES_PREFIJO);
	    mensaje.addLinea(GENERA_RUTAS);
	    mensaje.addLinea(gson.toJson(paquete, PaqueteBackend.class));
	    printToBackend(pw, mensaje);
	    result = gson.fromJson(scan.nextLine(), RutaDeVueloBackend[].class);
	    
	    response.close();
	    socket.close();
	    pw.close();
	    os.close();
	    return result;
	}
	public int getCapacidadDisponibleAlmacenEnFecha(String almacenNombre, Fecha f) throws UnknownHostException, IOException {
		Gson gson = new Gson();
	    Socket socket = new Socket("localhost", 51717);
	    OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(PAQUETES_PREFIJO);
	    mensaje.addLinea(CAPACIDAD_DISPONIBLE_ALMACEN);
	    mensaje.addLinea(gson.toJson(f, Fecha.class));
	    mensaje.addLinea(almacenNombre);
	    printToBackend(pw, mensaje);
	    
	    int result = Integer.parseInt(leeLinea(scan));
	    response.close();
	    socket.close();
	    pw.close();
	    os.close();
	    return result;
	}
	private String leeLinea(Scanner in) {
		return in.nextLine();
	}
	public void start() throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 51717);
	    OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(START);
	    printToBackend(pw, mensaje);
	 
	    socket.close();
	    pw.close();
	    os.close();
	}
	public void restart() throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 51717);
	    OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(RESTART);
	    printToBackend(pw, mensaje);
	 
	    socket.close();
	    pw.close();
	    os.close();
	}
	public int crearSesionSimulacion(int minutosSesion, int dias) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 51717);
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(SIMULACION_PREFIJO);
	    mensaje.addLinea(CREAR_SESION_SIMULACION);
	    mensaje.addLinea("" + minutosSesion);
	    mensaje.addLinea("" + dias);
	    printToBackend(pw, mensaje);
	    Mensaje result;
	    Gson gson = new Gson();
	    result = gson.fromJson(scan.nextLine(), Mensaje.class);
	    int id = Integer.parseInt(result.get(0));
	    socket.close();
	    pw.close();
	    os.close();
	    return id;
	}
	public boolean startSimulacion(int idSimulacion) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 51717);
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(SIMULACION_PREFIJO);
	    mensaje.addLinea(START_SIMULACION);
	    mensaje.addLinea("" + idSimulacion);
	    printToBackend(pw, mensaje);
	    
	    Mensaje result;
	    Gson gson = new Gson();
	    result = gson.fromJson(scan.nextLine(), Mensaje.class);
	    boolean res = Boolean.parseBoolean(result.get(0));
	    socket.close();
	    pw.close();
	    os.close();
	    return res;
	}
	public void cambioCapacidadConexion(int idSimulacion, int idConexion,
			int nuevaCapacidad) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 51717);
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(SIMULACION_PREFIJO);
	    mensaje.addLinea(CAMBIO_CAPACIDAD_CONEXION);
	    mensaje.addLinea(idSimulacion);
	    mensaje.addLinea(idConexion);
	    mensaje.addLinea(nuevaCapacidad);
	    printToBackend(pw, mensaje);
	    
	    socket.close();
	    pw.close();
	    os.close();
	}
	public void cambioCapacidadAlmacen(int idSimulacion, int idAlmacen,
			int nuevaCapacidad) throws IOException {
		Socket socket = new Socket("localhost", 51717);
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(SIMULACION_PREFIJO);
	    mensaje.addLinea(CAMBIO_CAPACIDAD_ALMACEN);
	    mensaje.addLinea(idSimulacion);
	    mensaje.addLinea(idAlmacen);
	    mensaje.addLinea(nuevaCapacidad);
	    printToBackend(pw, mensaje);
	    
	    socket.close();
	    pw.close();
	    os.close();
	}
	public ResultadosQuerySimulacionDTO getQueryWindowSimulacion(
			int idSimulacion, Fecha inicio, Fecha fin) throws IOException {
		Socket socket = new Socket("localhost", 51717);
		OutputStream os = socket.getOutputStream();
		PrintWriter pw = new PrintWriter(os, true);
	    InputStream response = socket.getInputStream();
	    Scanner scan = new Scanner(response);
	    Gson gson = new Gson();
	    
	    Mensaje mensaje = new Mensaje();
	    mensaje.addLinea(SIMULACION_PREFIJO);
	    mensaje.addLinea(GET_DATOS_WINDOW_SIMULACION);
	    mensaje.addLinea(idSimulacion);
	    mensaje.addLinea(gson.toJson(inicio, Fecha.class));
	    mensaje.addLinea(gson.toJson(fin, Fecha.class));
	    printToBackend(pw, mensaje);
	    
	    ResultadosQuerySimulacionDTO result;
	    
	    result = gson.fromJson(scan.nextLine(), ResultadosQuerySimulacionDTO.class);
	    
	    socket.close();
	    pw.close();
	    os.close();
	    return result;
	}
}
